

-- Namespace
	local _,mod = ...


-- Reference
	local newplate = mod.newplate
		mod.newplate = nil


-- Event core
	local scripts = { base = {}, overlay = {}, name = {}, hpbar = {}, castbar = {} }
	function mod:event(frame,handler,func)
		if not func then
			frame,handler,func = 'base',frame,handler
		end
		if scripts[frame] then
			local stbl = scripts[frame][handler]
			if not stbl then
				stbl = {}
				scripts[frame][handler] = stbl
				stbl.call = function(self,...)
					local nfframe = self.nfframe or self.p.nfframe
					local succ,err
					for i = 1,#stbl do
						succ,err = pcall(stbl[i],nfframe,self,...)
						if not succ then
							mod.softerror(err)
						end
					end
				end
			end
			stbl[#stbl+1] = func
		end
	end


-- Frame prep
	local function OnUpdate(self)
		self:SetAlpha(0)
		
		local _,_,_,x,y = self.c.overlay:GetPoint()
		local pscale = self.c.overlay:GetEffectiveScale()
			x,y = x*pscale,y*pscale
		local nfframe = self.nfframe
		local nfscale = nfframe:GetEffectiveScale()
		local sub = nfframe:GetWidth() * .5
		nfframe:ClearAllPoints()
		nfframe:SetPoint('BOTTOMLEFT',floor((x-sub)/nfscale),floor(y/nfscale))
	end
	
	local function OnShow(self)
		self.nfframe:Show()
		OnUpdate(self)
	end
	
	local function OnHide(self)
		self.nfframe:Hide()
	end
	
	local function handle(plate)
		local overlay,name = plate:GetChildren()
		local hpbar,castbar = overlay:GetChildren()
		
		local _,castoverlay,castshield,casticon = castbar:GetRegions()
		local nametext = name:GetRegions()
		local glow,backdrop,highlight,lvltext,bossicon,raidicon,stateicon = overlay:GetRegions()
		
		local c = {
			base = plate,
			overlay = overlay,
			name = name,
			hpbar = hpbar,
			castbar = castbar,
		}
		for _,c in pairs(c) do
			c.p = plate
		end
		plate.c = c
		
		local r = {
			castoverlay = castoverlay,
			castshield = castshield,
			casticon = casticon,
			nametext = nametext,
			glow = glow,
			backdrop = backdrop,
			highlight = highlight,
			lvltext = lvltext,
			bossicon = bossicon,
			raidicon = raidicon,
			stateicon = stateicon,
		}
		for _,r in pairs(r) do
			r.p = plate
		end
		plate.r = r
		
		local nfframe = newplate()
		plate.nfframe = nfframe
		
		plate:SetScript('OnShow',OnShow)
		plate:SetScript('OnHide',OnHide)
		plate:SetScript('OnUpdate',OnUpdate)
		
		OnShow(plate)
		OnUpdate(plate)
		
		local f,os
		for frame,handlers in pairs(scripts) do
			f = c[frame]
			if f then
				for handler,stbl in pairs(handlers) do
					if f:HasScript(handler) then
						if f:GetScript(handler) then
							f:HookScript(handler,stbl.call)
						else
							f:SetScript(handler,stbl.call)
						end
					end
				end
				os = handlers['OnShow']
				if os and f:IsShown() then
					os.call(f)
				end
			end
		end
	end


-- Scanning
	local function scanhelp(low,high,...)
		local f,name
		for i = low,high do
			f = select(i,...)
			if not f.NFNAMEPLATE then
				name = f:GetName() or ''
				if name:find('^NamePlate%d+$') then
					handle(f)
					f.NFNAMEPLATE = true
				end
			end
		end
	end
	
	local n = 0
	mod:timer_register(0,true,function()
		local newn = WorldFrame:GetNumChildren()
		if newn > n then
			scanhelp(n+1,newn,WorldFrame:GetChildren())
			n = newn
		end
	end)
